<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2024/3/20
 * Time: 11:46
 */

namespace app\queue\redis;

use app\common\lib\RedisQueue;
use app\common\lib\TencentIvld;
use app\model\video\AsyncUploadVideoIvldModel;
use support\Cache;
use Webman\RedisQueue\Consumer;
use app\common\lib\TencentCos;

class AsyncVideoIvld  implements Consumer
{
    // 要消费的队列名
    public $queue = 'asyncVideoIvld';

    // 连接名，对应 plugin/webman/redis-queue/redis.php 里的连接`
    public $connection = 'default';

    protected $resultData = [];

    // 消费
    public function consume($data)
    {
        try{
            // 无需反序列化
            //var_export($data);
            //var_export('redis_queue_asyncUploadVideo');
            $result = $this->handle($data);
            @unlink($data['filepath']);

            RedisQueue::getInstance()->saveQueue($this->queue,$data,$result);
        }catch (\Exception $e){
            RedisQueue::getInstance()->saveQueue($this->queue,$data,['error'=>$e->getMessage()]);
        }

        //保存上传视频进度
        $this->saveUploadVideoIvld($data);
    }

    protected function handle($data)
    {
        $cacheKey = 'async_vieo_ivld_'.$data['requestid'];

        //todo 1 首先上传视频
        $result = TencentCos::getInstance()->asyncUploadFile($data['filepath'],$data['requestid'],'video');
        $this->resultData['upload_video'] = !empty($result['Location']) ? ['https://'.$result['Location']] : [];

        if(empty($result['Location'])){
            $this->resultData['result'] = ['status'=>'-1','step'=>'1','msg'=>$result['msg']??'','progress'=>0];
            Cache::set($cacheKey,['status'=>'-1','step'=>'1','msg'=>$result['msg']??'','progress'=>0],300);
            return ['error'=>$result['msg']??'upload file fail'];
        }
        $videoLink = 'https://'.$result['Location'];

        //todo 2 导入媒体
        $result = TencentIvld::getInstance()->importMediaFile($videoLink);
        $mediaId = $result['MediaId'];
        while (true){
            //状态名	状态值	状态描述
            //MEDIA_STATUS_INVALID	0	非法状态
            //MEDIA_STATUS_WAITING	1	等待中
            //MEDIA_STATUS_DOWNLOADING	2	下载中
            //MEDIA_STATUS_DOWNLOADED	3	下载完成
            //MEDIA_STATUS_DOWNLOAD_FAILED	4	下载失败(已废弃)
            //MEDIA_STATUS_TRANSCODING	5	转码中
            //MEDIA_STATUS_TRANSCODED	6	转码完成
            //MEDIA_STATUS_TRANCODE_FAILED	7	转码失败(已废弃)
            //MEDIA_STATUS_SUCCESS	8	媒资文件状态就绪，可发起任务
            //MEDIA_STATUS_EXPIRED	9	媒资文件已过期
            //MEDIA_STATUS_FAILED	10	媒资导入失败
            $describeMedia = TencentIvld::getInstance()->describeMedia($mediaId);
            $this->resultData['import_media_file'] = $describeMedia;
            if(in_array($describeMedia['MediaInfo']['Status'],[0,4,7,9,10])){
                $cacheData = [
                    'step'=>'2',
                    'status'=>$describeMedia['MediaInfo']['Status']??'-1',
                    'msg'=>$describeMedia['MediaInfo']['FailedReason']??'',
                    'progress'=>0,
                ];
                $this->resultData['result'] = $cacheData;
                Cache::set($cacheKey,$cacheData,300);
                return ['error'=>$describeMedia['MediaInfo']['FailedReason']??'import Media File fail'];
            }

            if(!empty($describeMedia['MediaInfo']['Status']) && $describeMedia['MediaInfo']['Status']==8){
                usleep(10000);
                $cacheData = [
                    'step'=>'2',
                    'status'=>$describeMedia['MediaInfo']['Status'],
                    'msg'=>'success',
                    'progress'=>100,
                ];
                $this->resultData['result'] = $cacheData;
                Cache::set($cacheKey,$cacheData,300);
                break;
            }else{
                $cacheData = [
                    'step'=>'2',
                    'status'=>$describeMedia['MediaInfo']['Status'],
                    'msg'=>'Waiting import Media File',
                    'progress'=>$describeMedia['MediaInfo']['Progress'],
                ];
                $this->resultData['result'] = $cacheData;
                Cache::set($cacheKey,$cacheData,300);
            }
            usleep(500000);
        }

        //todo 3 创建任务
        $taskResult = TencentIvld::getInstance()->createTask($mediaId);
        $taskId = $taskResult['TaskId'];
        while (true){
            //TASK_STATUS_INVALID	0	非法的任务状态
            //TASK_STATUS_WAITING	1	排队中
            //TASK_STATUS_ANALYSING	2	任务分析中
            //TASK_STATUS_ANALYSED	3	任务分析完成
            //TASK_STATUS_SNAPSHOT_CREATING	4	任务结果快照生成中
            //TASK_STATUS_SNAPSHOT_CREATED	5	任务结果快照生成完成
            //TASK_STATUS_RESULT_UPLOADING	6	任务结果快照上传中
            //TASK_STATUS_RESULT_UPLOADED	7	任务结果快照上传完成
            //TASK_STATUS_SUCCESS	8	任务执行完成
            //TASK_STATUS_FAILED	9	任务执行失败
            $describeTask = TencentIvld::getInstance()->describeTask($taskId);
            $this->resultData['create_task'] = $describeTask;
            if(in_array($describeTask['TaskInfo']['TaskStatus'],[9])){
                $cacheData = [
                    'step'=>'3',
                    'status'=>$describeTask['TaskInfo']['TaskStatus']??'-1',
                    'msg'=>$describeTask['TaskInfo']['FailedReason']??'',
                    'progress'=>0,
                ];
                $this->resultData['result'] = $cacheData;
                Cache::set($cacheKey,$cacheData,300);
                return ['error'=>$describeTask['TaskInfo']['FailedReason']??'create Task fail'];
            }

            if(!empty($describeTask['TaskInfo']['TaskStatus']) && $describeTask['TaskInfo']['TaskStatus']==8){
                usleep(10000);
                $cacheData = [
                    'step'=>'3',
                    'status'=>$describeTask['TaskInfo']['TaskStatus'],
                    'msg'=>'success',
                    'progress'=>100,
                ];
                $this->resultData['result'] = $cacheData;
                Cache::set($cacheKey,$cacheData,300);
                break;
            }else{
                $cacheData = [
                    'step'=>'3',
                    'status'=>$describeTask['TaskInfo']['TaskStatus'],
                    'msg'=>'Waiting Create Task',
                    'progress'=>$describeTask['TaskInfo']['TaskProgress'],
                ];
                $this->resultData['result'] = $cacheData;
                Cache::set($cacheKey,$cacheData,300);
            }
            usleep(500000);
        }

        //todo 4 获取任务分析结果
        $taskDetail = TencentIvld::getInstance()->describeTaskDetail($taskId);
        $this->resultData['describe_task_detail'] = $taskDetail;

        $cacheData = [
            'step'=>'4',
            'status'=>8,
            'msg'=>'success',
            'progress'=>100,
            'data'=>$taskDetail
        ];
        $this->resultData['result'] = $cacheData;
        Cache::set($cacheKey,$cacheData,300);

        return $taskDetail;
    }

    // 消费失败回调
    /*
    $package = [
        'id' => 1357277951, // 消息ID
        'time' => 1709170510, // 消息时间
        'delay' => 0, // 延迟时间
        'attempts' => 2, // 消费次数
        'queue' => 'send-mail', // 队列名
        'data' => ['to' => 'tom@gmail.com', 'content' => 'hello'], // 消息内容
        'max_attempts' => 5, // 最大重试次数
        'error' => '错误信息' // 错误信息
    ]
    */
    public function onConsumeFailure(\Throwable $e, $package)
    {
//        echo "consume failure\n";
//        echo $e->getMessage() . "\n";
//        // 无需反序列化
//        var_export($package);

        RedisQueue::getInstance()->saveQueue($this->queue,$package['data'],['error'=>$e->getMessage()]);
    }

    public function saveUploadVideoIvld($data)
    {
        $insert = [
            'requestid'=>$data['requestid']??'',
            'local_video_path'=>$data['filepath']??'',
            'video_link'=>json_encode($this->resultData['upload_video']??[], 256),
            'import_media_file'=>json_encode($this->resultData['import_media_file']??[], 256),
            'create_task'=>json_encode($this->resultData['create_task']??[], 256),
            'describe_task_detail'=>json_encode($this->resultData['describe_task_detail']??[], 256),
            'result'=>json_encode($this->resultData['result']??[], 256),
            'created_at'=>date('Y-m-d H:i:s'),
            'update_at'=>date('Y-m-d H:i:s'),
        ];
        AsyncUploadVideoIvldModel::getInstance()->insert($insert);
    }

}